HAL FMC NOR initialization and configuration functions migration ¶
The goal of this page is to show how to migrate the initialization sequence using STM32CubeMX2:
Open STM32CubeMX2 FMC NOR configuration panel.
Configure the SW layer HAL.
Configure the FMC NOR main features.
Configure the FMC NOR advanced features.
Configure the FMC NOR security and privilege features if needed.
Configure the FMC NOR GPIO pins.
Generate the code.
Note
The FMC NOR peripheral supports the following read and write access modes:
Asynchronous memory
HAL_NOR_SetConfigRdWrAsyncMemory(), with an optional configuration to set different timings for write operations when needed usingHAL_NOR_SetWrAsyncTimings().Synchronous/Asynchronous memory
HAL_NOR_SetConfigRdSyncWrAsyncMemory().
HAL FMC NOR configuration panel ¶
Create a new project with STM32CubeMX2, start by enabling the FMC instance as NOR, as shown in this example with the selected FMC-NOR_PSRAM1, then start the initialization and the main configuration.
HAL FMC NOR main features configuration ¶
Configure the FMC NOR main features.
HAL FMC NOR advanced features configuration ¶
Configure the advanced FMC NOR features.
HAL FMC NOR security and privilege features configuration ¶
Configure the FMC NOR security and privilege features if needed.
GPIO configuration ¶
Configure GPIO pins.
Generated FMC NOR initialization and de-initialization sequences ¶
The FMC NOR initialization sequence is generated in the
mx_fmc_nor_psram1_nor_init
function in
mx_fmc.c
file
under
$YOUR_PROJECT_NAME$/$YOUR_PROJECT_NAME$_SW/generated/STM32Cube_CodeGen.
Related concepts:
|
Topic |
Code Snippet HAL1 |
Code Snippet HAL2 |
|---|---|---|
|
Handle declaration |
NOR_HandleTypeDef hnor1;
GPIO_InitTypeDef GPIO_InitStruct ={0};
|
hal_nor_handle_t hNOR_PSRAM1;
hal_nor_config_t nor_config;
hal_nor_rd_wr_async_memory_config_t p_config;
hal_gpio_config_t gpio_config;
|
|
Initialization and configuration sequence |
static void MX_FMC_Init(void)
{
FMC_NORSRAM_TimingTypeDef Timing = {0};
/** Perform the NOR1 memory initialization sequence
*/
hnor1.Instance = FMC_NORSRAM_DEVICE;
hnor1.Extended = FMC_NORSRAM_EXTENDED_DEVICE;
/* hnor1.Init */
hnor1.Init.NSBank = FMC_NORSRAM_BANK1;
hnor1.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
hnor1.Init.MemoryType = FMC_MEMORY_TYPE_NOR;
hnor1.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16;
hnor1.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
hnor1.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
hnor1.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
hnor1.Init.WriteOperation = FMC_WRITE_OPERATION_DISABLE;
hnor1.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
hnor1.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;
hnor1.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE;
hnor1.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
hnor1.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
hnor1.Init.WriteFifo = FMC_WRITE_FIFO_ENABLE;
hnor1.Init.NBLSetupTime = 0;
hnor1.Init.PageSize = FMC_PAGE_SIZE_NONE;
hnor1.Init.MaxChipSelectPulse = DISABLE;
/* Timing */
Timing.AddressSetupTime = 3;
Timing.AddressHoldTime = 1;
Timing.DataSetupTime = 3;
Timing.DataHoldTime = 1;
Timing.BusTurnAroundDuration = 1;
Timing.CLKDivision = 2;
Timing.DataLatency = 2;
Timing.AccessMode = FMC_ACCESS_MODE_A;
/* ExtTiming */
if (HAL_NOR_Init(&hnor1, &Timing, NULL) != HAL_OK)
{
Error_Handler( );
}
}
static void HAL_FMC_MspInit(void){
if (FMC_Initialized) {
return;
}
FMC_Initialized = 1;
__HAL_RCC_FMC_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_4 | GPIO_PIN_7 | GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_5 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_12 | GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
}
void HAL_NOR_MspInit(NOR_HandleTypeDef* hnor)
{
HAL_FMC_MspInit();
}
static void MX_GPIO_Init(void)
{
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
}
|
hal_nor_handle_t *mx_fmc_nor_psram1_nor_init(void)
{
if (HAL_NOR_Init(&hNOR_PSRAM1, HAL_NOR1) != HAL_OK)
{
return NULL;
}
HAL_RCC_FMC_EnableClock();
nor_config.wait_signal_polarity = HAL_NOR_WAIT_SIGNAL_POLARITY_LOW;
if (HAL_NOR_SetConfig(&hNOR_PSRAM1, &nor_config) != HAL_OK)
{
return NULL;
}
/* Asynchronous read and write with identical timing for both operation */
p_config.memory.mux_data_addr = HAL_NOR_MUX_DATA_ADDR_DISABLE;
p_config.timings.access_timings.addr_setup_nsec = 20;
p_config.timings.access_timings.addr_hold_nsec = 10;
p_config.timings.access_timings.data_setup_nsec = 30;
p_config.timings.access_timings.data_hold_nsec = 10;
p_config.timings.async_wait = HAL_NOR_ASYNC_WAIT_SIGNAL_DISABLE;
p_config.timings.bus_turnaround_nsec = 10;
if (HAL_NOR_SetConfigRdWrAsyncMemory(&hNOR_PSRAM1, &p_config) != HAL_OK)
{
return NULL;
}
HAL_NOR_EnableMemory(&hNOR_PSRAM1);
HAL_RCC_GPIOC_EnableClock();
HAL_RCC_GPIOD_EnableClock();
HAL_RCC_GPIOA_EnableClock();
HAL_RCC_GPIOB_EnableClock();
gpio_config.mode = HAL_GPIO_MODE_ALTERNATE;
gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
gpio_config.pull = HAL_GPIO_PULL_NO;
gpio_config.speed = HAL_GPIO_SPEED_FREQ_LOW;
gpio_config.alternate = HAL_GPIO_AF_12;
HAL_GPIO_Init(HAL_GPIOC, HAL_GPIO_PIN_1 | HAL_GPIO_PIN_2 | HAL_GPIO_PIN_3 | HAL_GPIO_PIN_4 | HAL_GPIO_PIN_5, &gpio_config);
gpio_config.mode = HAL_GPIO_MODE_ALTERNATE;
gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
gpio_config.pull = HAL_GPIO_PULL_NO;
gpio_config.speed = HAL_GPIO_SPEED_FREQ_LOW;
gpio_config.alternate = HAL_GPIO_AF_12;
HAL_GPIO_Init(HAL_GPIOD, HAL_GPIO_PIN_12, &gpio_config);
gpio_config.mode = HAL_GPIO_MODE_ALTERNATE;
gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
gpio_config.pull = HAL_GPIO_PULL_NO;
gpio_config.speed = HAL_GPIO_SPEED_FREQ_LOW;
gpio_config.alternate = HAL_GPIO_AF_10;
HAL_GPIO_Init(HAL_GPIOD, HAL_GPIO_PIN_8 | HAL_GPIO_PIN_9, &gpio_config);
gpio_config.mode = HAL_GPIO_MODE_ALTERNATE;
gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
gpio_config.pull = HAL_GPIO_PULL_NO;
gpio_config.speed = HAL_GPIO_SPEED_FREQ_LOW;
gpio_config.alternate = HAL_GPIO_AF_12;
HAL_GPIO_Init(HAL_GPIOA, HAL_GPIO_PIN_12 | HAL_GPIO_PIN_11 | HAL_GPIO_PIN_10 | HAL_GPIO_PIN_9 | HAL_GPIO_PIN_2 | HAL_GPIO_PIN_1 | HAL_GPIO_PIN_0 | HAL_GPIO_PIN_5, &gpio_config);
gpio_config.mode = HAL_GPIO_MODE_ALTERNATE;
gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
gpio_config.pull = HAL_GPIO_PULL_NO;
gpio_config.speed = HAL_GPIO_SPEED_FREQ_LOW;
gpio_config.alternate = HAL_GPIO_AF_12;
HAL_GPIO_Init(HAL_GPIOB, HAL_GPIO_PIN_11 | HAL_GPIO_PIN_15 | HAL_GPIO_PIN_5 | HAL_GPIO_PIN_13 | HAL_GPIO_PIN_12 | HAL_GPIO_PIN_2, &gpio_config);
gpio_config.mode = HAL_GPIO_MODE_ALTERNATE;
gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
gpio_config.pull = HAL_GPIO_PULL_UP;
gpio_config.speed = HAL_GPIO_SPEED_FREQ_LOW;
gpio_config.alternate = HAL_GPIO_AF_12;
HAL_GPIO_Init(HAL_GPIOB, HAL_GPIO_PIN_4, &gpio_config);
gpio_config.mode = HAL_GPIO_MODE_ALTERNATE;
gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
gpio_config.pull = HAL_GPIO_PULL_NO;
gpio_config.speed = HAL_GPIO_SPEED_FREQ_VERY_HIGH;
gpio_config.alternate = HAL_GPIO_AF_12;
HAL_GPIO_Init(HAL_GPIOB, HAL_GPIO_PIN_3, &gpio_config);
gpio_config.mode = HAL_GPIO_MODE_ALTERNATE;
gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
gpio_config.pull = HAL_GPIO_PULL_UP;
gpio_config.speed = HAL_GPIO_SPEED_FREQ_LOW;
gpio_config.alternate = HAL_GPIO_AF_12;
HAL_GPIO_Init(HAL_GPIOA, HAL_GPIO_PIN_15, &gpio_config);
gpio_config.mode = HAL_GPIO_MODE_ALTERNATE;
gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
gpio_config.pull = HAL_GPIO_PULL_NO;
gpio_config.speed = HAL_GPIO_SPEED_FREQ_LOW;
gpio_config.alternate = HAL_GPIO_AF_10;
HAL_GPIO_Init(HAL_GPIOB, HAL_GPIO_PIN_0, &gpio_config);
gpio_config.mode = HAL_GPIO_MODE_ALTERNATE;
gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL;
gpio_config.pull = HAL_GPIO_PULL_NO;
gpio_config.speed = HAL_GPIO_SPEED_FREQ_LOW;
gpio_config.alternate = HAL_GPIO_AF_7;
HAL_GPIO_Init(HAL_GPIOB, HAL_GPIO_PIN_1, &gpio_config);
return &hNOR_PSRAM1;
}
|
|
Deinitialization sequence |
static void HAL_FMC_MspDeInit(void){
if (FMC_DeInitialized) {
return;
}
FMC_DeInitialized = 1;
/* Peripheral clock enable */
__HAL_RCC_FMC_CLK_DISABLE();
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_4 | GPIO_PIN_7 | GPIO_PIN_5);
HAL_GPIO_DeInit(GPIOF, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_5 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_12 | GPIO_PIN_13);
}
void HAL_NOR_MspDeInit(NOR_HandleTypeDef* hnor){
HAL_FMC_MspDeInit();
}
|
void mx_fmc_nor_psram1_nor_deinit(void)
{
/* De-initialize all GPIO pins associated with FMC */
HAL_GPIO_DeInit(HAL_GPIOC, HAL_GPIO_PIN_1 | HAL_GPIO_PIN_2 | HAL_GPIO_PIN_3 | HAL_GPIO_PIN_4 | HAL_GPIO_PIN_5);
HAL_GPIO_DeInit(HAL_GPIOD, HAL_GPIO_PIN_8 | HAL_GPIO_PIN_9 | HAL_GPIO_PIN_12);
HAL_GPIO_DeInit(HAL_GPIOA, HAL_GPIO_PIN_0 | HAL_GPIO_PIN_1 | HAL_GPIO_PIN_2 | HAL_GPIO_PIN_5 | HAL_GPIO_PIN_9 | \
HAL_GPIO_PIN_10 | HAL_GPIO_PIN_11 | HAL_GPIO_PIN_12 | HAL_GPIO_PIN_15);
HAL_GPIO_DeInit(HAL_GPIOB, HAL_GPIO_PIN_0 | HAL_GPIO_PIN_1 | HAL_GPIO_PIN_2 | HAL_GPIO_PIN_3 | HAL_GPIO_PIN_4 | \
HAL_GPIO_PIN_5 | HAL_GPIO_PIN_11 | HAL_GPIO_PIN_12 | HAL_GPIO_PIN_13 | HAL_GPIO_PIN_15);
HAL_NOR_DeInit(&hNOR_PSRAM1);
}
|
All subbanks configuration ¶
|
HAL1 code snippet |
HAL2 code snippet |
|---|---|
HAL_Init();
// --- NOR bank (1) and sub-banks Initialization NORx (x = 1 to 4) ---
for (int i = 0; i < 4; i++)
{
hnor[i].Instance = FMC_NORSRAM_DEVICE;
hnor[i].Extended = FMC_NORSRAM_EXTENDED_DEVICE;
hnor[i].Init.NSBank = FMC_NORSRAM_BANK1 + i;
hnor[i].Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
hnor[i].Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
hnor[i].Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
hnor[i].Init.WrapMode = FMC_WRAP_MODE_DISABLE;
hnor[i].Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
hnor[i].Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
hnor[i].Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;
hnor[i].Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
hnor[i].Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
// Fill static configuration
hnor[i].Init.MemoryType = FMC_MEMORY_TYPE_NOR;
/* ---------------------------------------------------------- */
hnor[i].Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
// Fill memory configuration
hnor[i].Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16;
hnor[i].Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE;
Nor_Timing.AddressSetupTime = 2;
Nor_Timing.AddressHoldTime = 1;
Nor_Timing.DataSetupTime = 2;
Nor_Timing.DataHoldTime = 1;
Nor_Timing.BusTurnAroundDuration = 1;
Nor_Timing.CLKDivision = 2;
Nor_Timing.DataLatency = 2;
/* Optional: Set different write timings if needed */
Nor_Wr_Timing.AddressSetupTime = 3;
Nor_Wr_Timing.AddressHoldTime = 1;
Nor_Wr_Timing.DataSetupTime = 3;
Nor_Wr_Timing.DataHoldTime = 1;
Nor_Wr_Timing.BusTurnAroundDuration = 1;
Nor_Wr_Timing.AccessMode = FMC_ACCESS_MODE_A;
HAL_NOR_Init(&hnor[i], &Nor_Timing, &Nor_Wr_Timing);
}
|
hal_nor_handle_t* hnor [4] ={hnor1, hnor2, hnor3, hnor4};
hal_nor_t nor_instance[4] = {HAL_NOR1, HAL_NOR2, HAL_NOR3, HAL_NOR4};
HAL_Init();
// Initialize the NOR handle and associate to the HAL NORx instance
for (int i = 0; i < 4; i++)
{
HAL_NOR_Init(&hnor[i], nor_instance[i]);
}
// Fill static configuration of FMC peripheral
nor_config.wait_signal_polarity = HAL_NOR_WAIT_SIGNAL_POLARITY_LOW;
/* Fill memory configuration */
nor_mem_config.memory.mux_data_addr = HAL_NOR_MUX_DATA_ADDR_DISABLE;
nor_mem_config.timings.async_wait = HAL_NOR_ASYNC_WAIT_SIGNAL_DISABLE;
nor_mem_config.timings.access_timings.addr_setup_nsec = 20;
nor_mem_config.timings.access_timings.addr_hold_nsec = 10;
nor_mem_config.timings.access_timings.data_setup_nsec = 20;
nor_mem_config.timings.access_timings.data_hold_nsec = 10;
nor_mem_config.timings.bus_turnaround_nsec = 10;
/* Optional: Set different write timings if needed */
nor_wr_timings.async_access_timings.addr_setup_nsec = 30;
nor_wr_timings.async_access_timings.addr_hold_nsec = 10;
nor_wr_timings.async_access_timings.data_setup_nsec = 30;
nor_wr_timings.async_access_timings.data_hold_nsec = 10;
nor_wr_timings.bus_turnaround_nsec = 10;
nor_wr_timings.read_access_mode = HAL_NOR_ACCESS_MODE_B;
nor_wr_timings.write_access_mode = HAL_NOR_ACCESS_MODE_B;
for (int i = 0; i < 4; i++)
{
HAL_NOR_SetConfig(&hnor[i], &nor_config); // FMC peripheral configuration
HAL_NOR_SetConfigRdWrAsyncMemory(&hnor[i], &nor_mem_config); // FMC memory configuration
HAL_NOR_SetWrAsyncTimings(&hnor[i], &nor_wr_timings); // Optional: FMC write timing configuration when different timing needed for write operation
HAL_NOR_EnableMemory(&hnor[i]); // Enable the NOR sub-bank x
}
|